package top.jianx.music.base;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.SneakyThrows;
import top.jianx.music.provider.netease.request.NeteaseSearchMusiRequestCallback;

import java.io.IOException;

/**
 * 为统一http请求和解析返回数据而封装的基类
 * @param <TResult> 返回数据泛型
 *
 * @author Jianx <jianx70687547@gmail.com>
 * @date 2022/1/16 11:46
 */
public abstract class BaseRequest<TResult> {
    /**
     * 异步请求方式（推荐使用此种方式）
     *
     * @param callback 回调接口
     */
    @SneakyThrows
    public final TResult requestAsync(final NeteaseSearchMusiRequestCallback callback) {
        HttpRequest request = buildRequest();
        TResult parsedResult = null;
        try {
            parsedResult = parseResult(request.executeAsync());
            callback.onSuccess(parsedResult);
        } catch (IOException ex) {
            callback.onFailure(ex);
        }
        return parsedResult;
    }

    /**
     * 同步请求方式
     *
     * @return 获取结果
     * @throws IOException
     */
    public final TResult requestSync() throws IOException {
        HttpRequest request = buildRequest();
        HttpResponse response = request.execute(useProxy());
        return parseResult(response);
    }

    protected static String responseBodyToString(HttpResponse response) throws IOException {
        return response.body();
    }

    /**
     * 需要构造的请求
     *
     * @return {@linkplain HttpResponse}
     */
    protected abstract HttpRequest buildRequest();

    /**
     * 解析response
     *
     * @param response {@linkplain HttpResponse} 响应
     * @return {@linkplain TResult} 返回结果
     * @throws IOException
     */
    protected abstract TResult parseResult(HttpResponse response) throws IOException;

    /**
     * 是否使用代理
     *
     * @return 是否使用代理
     */
    protected boolean useProxy() {
        return false;
    }

}
